package com.dx.mes.service.special.service;

import com.dx.common.table.ppt.Bis_path;
import com.dx.common.table.ppt.RetSampTplDef;
import com.dx.common.table.ppt.RetSlotDef;
import com.dx.mes.common.dao.*;
import com.dx.mes.common.transcoder.util.AppContext;
import com.dx.mes.common.transcoder.util.JacksonUtil;
import com.dx.mes.common.transcoder.util.LogUtils;
import com.dx.mes.common.transcoder.util.Util;
import com.dx.mes.facade.special.service.IFspsmprlnService;
import com.dx.mes.facade.special.tx.Fspsmprln.*;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.sql.Timestamp;
import java.util.*;

import static com.dx.mes.common.bean.def.GenericDef.*;
import static com.dx.mes.common.bean.def.GenericDef.E_FIPINQSHT_INVALID_INPUT;

/**
 * Created by tl on 2017/7/12.
 */
@Service("fspsmprlnService")
public class FspsmprlnService implements IFspsmprlnService {
    private LogUtils logUtils;
    private static String TX_NAME = "FSPSMPRLN";

    @Autowired
    private IRetSampTplDefDao fspsmprlnDao;
    @Autowired
    private IBisPathDao bisPathDao;
    @Autowired
    private IRetSlotDefDao retSlotDefDao;


    public String subMainProc(String evt_no,String strInMsg) {
        AppContext.clear();
        AppContext.setCurrServiceName(FspsmprlnService.class.getSimpleName());
        AppContext.setCurrEventNumber(evt_no);
        logUtils = new LogUtils(FspsmprlnService.class);
        logUtils.info("[InTrx:" + strInMsg + "]");

        String outMsg = "";
        FspsmprlnI inTrx = new FspsmprlnI();
        FspsmprlnO outTrx = new FspsmprlnO();

        outTrx.setTrx_id(TX_NAME);
        outTrx.setType_id(TRX_OUT);
        outTrx.setRtn_code(String.valueOf(RETURN_CODE_SET_ERROR));

        try {
            inTrx = JacksonUtil.fromJson(strInMsg, FspsmprlnI.class);

            subMainProc2(inTrx.getAction_flg().toCharArray()[0],inTrx,outTrx);
            if (!outTrx.getRtn_code().equals(RETURN_CODE_OK)) {
                TransactionAspectSupport.currentTransactionStatus()
                        .setRollbackOnly();
            } else {
                fspsmprlnDao.flushCurSession();
            }
        } catch (Exception ex) {
            outTrx.setRtn_mesg(ex.toString());
            outTrx.setRtn_code(RETURN_CODE_UNKNOWN);
            logUtils.error(Util.stackTraceToString(ex));
            TransactionAspectSupport.currentTransactionStatus()
                    .setRollbackOnly();
        } finally {
            outMsg = JacksonUtil.toJSONStr(outTrx);
            logUtils.info("[OutTrx:" + outTrx + "]");
        }
        return outMsg;
    }

    private void subMainProc2(char actionType,FspsmprlnI inTrx,FspsmprlnO outTrx) {

        switch (actionType) {
            case 'Q' :
                findRelationList(inTrx,outTrx);
                break;
            case 'S' :
                findSlotListByAct(inTrx,outTrx);
                break;
            case 'D' :
                deleteBySeqId(inTrx,outTrx);
                break;
            case 'A' :
                saveToSamp(inTrx,outTrx);
                break;
            default: {
                String gszMsgBuf = "Invalide type input: [" + actionType + "]";
                outTrx.setRtn_code(String.valueOf(E_FIPINQSHT_INVALID_INPUT));
                outTrx.setRtn_mesg(gszMsgBuf);
                return;
            }
        }
    }

    private void findSlotListByAct(FspsmprlnI inTrx, FspsmprlnO outTrx) {
        FspsmprlnIA fspsmprlnIA = inTrx.getIary().get(0);
        String act_seq_id = fspsmprlnIA.getAct_seq_id();
        String sql = "select * from ret_slot_def where 1 = 1 and act_seq_id = '"+act_seq_id+"'";
        List<RetSlotDef> retSlotDefList = retSlotDefDao.findBySQL(sql, RetSlotDef.class);
        outTrx.setOaryS(retSlotDefList);
        outTrx.setRtn_code(RETURN_CODE_OK);
        outTrx.setTbl_cnt(retSlotDefList.size());

    }

    private void saveToSamp(FspsmprlnI inTrx, FspsmprlnO outTrx) {
        FspsmprlnIA fspsmprlnIA = inTrx.getIary().get(0);
        String tpl_seq_id = UUID.randomUUID().toString().replace("-", "");
        String unq_seq_id = UUID.randomUUID().toString().replace("-", "").substring(0,25);
        String mdl_id_fk = fspsmprlnIA.getMdl_id_fk();                      //p
        String ope_no_fk = fspsmprlnIA.getOpe_no_fk();      //操作代码                      //p
        String path_id_fk = fspsmprlnIA.getPath_id_fk(); //工艺路线代码                      //p
        String path_ver_fk = fspsmprlnIA.getPath_ver_fk(); //工艺路线版本                      //p
        String samp_path_id_fk = fspsmprlnIA.getSamp_path_id_fk();                      //p
        String samp_path_ver_fk = fspsmprlnIA.getSamp_path_ver_fk();                      //p
        String samp_tpl_id = fspsmprlnIA.getSamp_tpl_id();   //p
        String ope_id_fk = fspsmprlnIA.getOpe_id_fk();
        String ope_ver_fk = fspsmprlnIA.getOpe_ver_fk();
        String[] slot_arr = fspsmprlnIA.getSlot_arr();
        String evt_usr = fspsmprlnIA.getEvt_usr();
        String evt_note = fspsmprlnIA.getEvt_note();
        //判断业务主键
        boolean exitDefPrimer = isExitDefPrimer(mdl_id_fk, ope_no_fk, samp_path_id_fk, samp_path_ver_fk, path_id_fk, path_ver_fk, samp_tpl_id);
        if (exitDefPrimer == true) {
            outTrx.setRtn_code(RETURN_NULL_ERROR);
            outTrx.setRtn_mesg("业务主键重复");
            return;
        }

        //判断要设定的属于path的第几站
        String hql = "select * from bis_path where 1 = 1 and path_id_fk = '"+path_id_fk+"' and path_ver_fk = '"+path_ver_fk+"' and cr_ope_no = '"+ope_no_fk+"'";
        List<Bis_path> bySQL = bisPathDao.findBySQL(hql, Bis_path.class);
        Bis_path bis_path = bySQL.get(0);
        System.out.print("------------");
        if (bis_path.getCr_path_seq_no() == null ){
            outTrx.setRtn_code(RETURN_CODE_SET_ERROR);
            outTrx.setRtn_mesg("要设定的站点位置未知，请先维护！");
            return;
        }
        Integer cr_path_seq_no = bis_path.getCr_path_seq_no(); //本来的顺序
        //保存
        RetSampTplDef retSampTplDef = new RetSampTplDef();
        retSampTplDef.setEvt_cate("EVCT");
        retSampTplDef.setTpl_seq_id(tpl_seq_id);
        retSampTplDef.setUnq_seq_id(unq_seq_id);
        retSampTplDef.setMdl_id_fk(mdl_id_fk);
        retSampTplDef.setSamp_tpl_id(samp_tpl_id);
        retSampTplDef.setPath_id_fk(path_id_fk);
        retSampTplDef.setPath_ver_fk(path_ver_fk);
        retSampTplDef.setOpe_id_fk(ope_id_fk);
        retSampTplDef.setOpe_no_fk(ope_no_fk);
        retSampTplDef.setOpe_ver_fk(ope_ver_fk);
        retSampTplDef.setSamp_path_id_fk(samp_path_id_fk);
        retSampTplDef.setSamp_path_ver_fk(samp_path_ver_fk);

        //根据业务主键判断当前表序号 如果无则OPE_PRTY=1
        String sql = "select * from ret_samp_tpl_def where 1 = 1 and path_id_fk = '"+path_id_fk+"' order by ope_prty asc";// and path_ver_fk = '"+path_ver_fk+"' and cr_ope_no = '"+ope_no_fk+"'
        List<RetSampTplDef> bySQL1 = fspsmprlnDao.findBySQL(sql, RetSampTplDef.class);
        if (bySQL1 != null && bySQL1.size() > 0) {
            int index = 1;
            for (int i = 0; i < bySQL1.size(); i++) {
                RetSampTplDef retSampTplDef1 = bySQL1.get(i);
                String path_id_fk1 = retSampTplDef1.getPath_id_fk();
                String path_ver_fk1 = retSampTplDef1.getPath_ver_fk();
                String ope_no_fk1 = retSampTplDef1.getOpe_no_fk();
                String hql1 = "select * from bis_path where 1 = 1 and path_id_fk = '"+path_id_fk1+"' and path_ver_fk = '"+path_ver_fk1+"' and cr_ope_no = '"+ope_no_fk1+"'";
                List<Bis_path> bySQL2 = bisPathDao.findBySQL(hql1, Bis_path.class);
                Bis_path bySQLOnly = bySQL2.get(0);
                if (cr_path_seq_no - bySQLOnly.getCr_path_seq_no() > 0) {
                    index = index + 1;
                }
            }
            //对当前表排序，插入
            retSampTplDef.setOpe_prty(index);
            if (index < bySQL1.size()+1) {
                for (int i = index; i < bySQL1.size()+1; i++) {
                    RetSampTplDef retSampTplDef1 = bySQL1.get(i-1);
                    retSampTplDef1.setOpe_prty(retSampTplDef1.getOpe_prty()+1);
                }
            }

        } else {
            retSampTplDef.setOpe_prty(1);
        }
        if (slot_arr.length > 0){
            saveToSlot(slot_arr,tpl_seq_id,evt_usr,evt_note,outTrx);
        }
        //samp顺序
        String sq = "select * from ret_samp_tpl_def order by samp_prty desc";
        List<RetSampTplDef> bySQL2 = fspsmprlnDao.findBySQL(sq,RetSampTplDef.class);
        if (bySQL2 != null && bySQL2.size() > 0){
            Integer samp_prty = bySQL2.get(0).getSamp_prty();
            retSampTplDef.setSamp_prty(samp_prty+1);
        }else {
            retSampTplDef.setSamp_prty(1);
        }

        retSampTplDef.setEvt_usr(evt_usr);
        retSampTplDef.setEvt_timestamp(new Timestamp(new Date().getTime()));
        retSampTplDef.setEvt_note(evt_note);

        fspsmprlnDao.save(retSampTplDef);
        outTrx.setRtn_code(RETURN_CODE_OK);

    }

    private void findRelationList(FspsmprlnI inTrx, FspsmprlnO outTrx) {
        FspsmprlnIA fspsmprlnIA = inTrx.getIary().get(0);
        String mdl_id_fk = fspsmprlnIA.getMdl_id_fk();
        String ope_no_fk = fspsmprlnIA.getOpe_no_fk();
        String path_id_fk = fspsmprlnIA.getPath_id_fk();
        String path_ver_fk = fspsmprlnIA.getPath_ver_fk();
        String samp_path_id_fk = fspsmprlnIA.getSamp_path_id_fk();
        String samp_path_id_ver = fspsmprlnIA.getSamp_path_ver_fk();
        String samp_tpl_id = fspsmprlnIA.getSamp_tpl_id();

        String sql = "select * from ret_samp_tpl_def where 1 = 1";
        if (StringUtils.isNotBlank(mdl_id_fk)) {
            sql = sql + " and mdl_id_fk = '"+mdl_id_fk+"'";
        }
        if (StringUtils.isNotBlank(ope_no_fk)) {
            sql = sql + " and ope_no_fk = '"+ope_no_fk+"'";
        }
        if (StringUtils.isNotBlank(path_id_fk)) {
            sql = sql + " and path_id_fk = '"+path_id_fk+"'";
        }
        if (StringUtils.isNotBlank(path_ver_fk)) {
            sql = sql + " and path_ver_fk = '"+path_ver_fk+"'";
        }
        if (StringUtils.isNotBlank(samp_path_id_fk)) {
            sql = sql + " and samp_path_id_fk = '"+samp_path_id_fk+"'";
        }
        if (StringUtils.isNotBlank(samp_path_id_ver)) {
            sql = sql + " and samp_path_id_ver = '"+samp_path_id_ver+"'";
        }
        if (StringUtils.isNotBlank(samp_tpl_id)) {
            sql = sql + " and samp_tpl_id = '"+samp_tpl_id+"'";
        }
        List<RetSampTplDef> retSampTplDefList = fspsmprlnDao.findBySQL(sql, RetSampTplDef.class);
        if (retSampTplDefList != null && retSampTplDefList.size() > 0) {
            outTrx.setRtn_code(RETURN_CODE_OK);
            outTrx.setTbl_cnt(retSampTplDefList.size());
            outTrx.setOary(retSampTplDefList);
        } else {
            outTrx.setTbl_cnt(0);
            outTrx.setRtn_code(RETURN_CODE_OK);
        }

    }

    private void deleteBySeqId(FspsmprlnI inTrx, FspsmprlnO outTrx) {
        FspsmprlnIA fspsmprlnIA = inTrx.getIary().get(0);
        String[] rul_seq_ids = fspsmprlnIA.getRul_seq_ids();
        for (String rul_seq_id : rul_seq_ids) {
            fspsmprlnDao.deleteByKey(rul_seq_id);
        }
        outTrx.setRtn_code(RETURN_CODE_OK);
    }

    private void saveToSlot(String[] slot_arr, String rul_seq_id, String evt_usr, String ope_note, FspsmprlnO outTrx) {
        String sol = "select * from ret_slot_def where 1 = 1 and slot_set_typ = 1 ";
        if (StringUtils.isNotBlank(rul_seq_id)) {
             sol = sol + " and act_seq_id = '"+rul_seq_id+"'";
        }
        List<RetSlotDef> slotDefList = retSlotDefDao.findBySQL(sol, RetSlotDef.class);
        if (slotDefList != null && slotDefList.size() > 0){
            for (RetSlotDef retSlotDef : slotDefList) {
                for (int i =0; i < slot_arr.length; i ++) {
                    if ((slot_arr[i]).equals(retSlotDef.getSlot_no())) {
                        outTrx.setRtn_code(RETURN_NULL_ERROR);
                        outTrx.setRtn_mesg("slot业务主键重复 ");
                        return;
                    }
                }

            }
        }
        if (slot_arr.length > 0){
            for (int i = 0; i < slot_arr.length; i++) {
                RetSlotDef retSlotDef = new RetSlotDef();
                String slot_seq_id = UUID.randomUUID().toString().replace("-", "").substring(0, 25);
                String un_seq_id = UUID.randomUUID().toString().replace("-", "").substring(0, 25);
                retSlotDef.setSlot_seq_id(slot_seq_id);
                retSlotDef.setUnq_seq_id(un_seq_id);
                retSlotDef.setSlot_set_typ(1);
                retSlotDef.setAct_seq_id(rul_seq_id);
                retSlotDef.setSlot_no(slot_arr[i]);
                retSlotDef.setCrt_usr(evt_usr);
                retSlotDef.setSlot_get_method(1);
                retSlotDef.setCrt_timestamp(new Timestamp(new Date().getTime()));
                retSlotDef.setCrt_note(ope_note);
                retSlotDefDao.saveOrUpdate(retSlotDef);
            }

        }
    }

    //根据流水号查询表和对应的slot
    public FspsmprlnR export(String act_seq_id){

        FspsmprlnI fspsmprlnI = JacksonUtil.fromJson(act_seq_id, FspsmprlnI.class);
        String act_seq_id1 = fspsmprlnI.getAct_seq_id();
        FspsmprlnR fspsmprlnR = new FspsmprlnR();
        fspsmprlnR.setTpl_seq_id(act_seq_id1);
        String hql = "select * from ret_slot_def where act_seq_id = '"+act_seq_id1+"'";
        List<RetSlotDef> retSlotDefList = retSlotDefDao.findBySQL(hql, RetSlotDef.class);
        if (retSlotDefList != null && retSlotDefList.size() > 0) {
            fspsmprlnR.setRetSlotDefList(retSlotDefList);
        }
        //查询主表
        RetSampTplDef retSampTplDef = fspsmprlnDao.get(act_seq_id1);
        fspsmprlnR.setRetSampTplDef(retSampTplDef);
        return fspsmprlnR;
    }

    @Override
    public Fspsmprlnimport importExcel(ArrayList<RetSlotDef> retSlotDefs, ArrayList<RetSampTplDef> retSampTplDefs) {
        Fspsmprlnimport fspsmprlnimport = new Fspsmprlnimport();
        HashMap<Integer, String> reasonDef = new HashMap<>();
        HashMap<Integer, String> reasonSot = new HashMap<>();
        for (int i = 0; i < retSampTplDefs.size(); i++) {
            RetSampTplDef retSampTplDef = retSampTplDefs.get(i);
            String tpl_seq_id = retSampTplDef.getTpl_seq_id();
            String mdl_id_fk = retSampTplDef.getMdl_id_fk();
            String ope_no_fk = retSampTplDef.getOpe_no_fk();
            String samp_path_id_fk = retSampTplDef.getSamp_path_id_fk();
            String samp_path_ver_fk = retSampTplDef.getSamp_path_ver_fk();
            String path_id_fk = retSampTplDef.getPath_id_fk();
            String path_ver_fk = retSampTplDef.getPath_ver_fk();
            String samp_tpl_id = retSampTplDef.getSamp_tpl_id();
            String evt_note = retSampTplDef.getEvt_note();
            int cou = 1;
            for (RetSlotDef retSlotDef : retSlotDefs) {
                if (tpl_seq_id.equals(retSlotDef.getAct_seq_id())) {
                    cou = cou +1;
                }
            }
            boolean exitDefPrimer = isExitDefPrimer(mdl_id_fk, ope_no_fk, samp_path_id_fk, samp_path_ver_fk, path_id_fk, path_ver_fk, samp_tpl_id);
            if (exitDefPrimer == true) {
                reasonDef.put(i + 1, "业务主键重复");
                continue;
            } else if (cou <= 1) {
                reasonDef.put(i + 1, "该数据在slot中没有对应");
                continue;
            } else {
                String unid = UUID.randomUUID().toString().replace("-", "").substring(0, 25);
                retSampTplDef.setUnq_seq_id(unid);
                fspsmprlnDao.save(retSampTplDef);
            }
            //判断slot有无对应actseq
            int index = 1;
            int j ;
            for (j = 0; j < retSlotDefs.size(); j++) {
                RetSlotDef retSlotDef = retSlotDefs.get(j);
                String act_seq_id = retSlotDef.getAct_seq_id();
                String slot_no = retSlotDef.getSlot_no();
                Integer slot_set_typ = retSlotDef.getSlot_set_typ();
                boolean exitSlotPrimer = isExitSlotPrimer(String.valueOf(slot_set_typ), act_seq_id, slot_no);
                boolean sameByAct = isSameByAct(act_seq_id, slot_no);
                if (exitSlotPrimer == true) {
                    reasonSot.put(j+1,"业务主键重复");
                    continue;
                } else if (sameByAct == true) {
                    reasonSot.put(j+1,"同一个slot_no已经存在");
                    continue;
                } else {
                    String unid = UUID.randomUUID().toString().replace("-", "").substring(0, 25);
                    String slot_seq = UUID.randomUUID().toString().replace("-", "");
                    retSlotDef.setUnq_seq_id(unid);
                    retSlotDef.setSlot_seq_id(slot_seq);
                    retSlotDefDao.save(retSlotDef);
                }


            }


        }
        fspsmprlnimport.setReasonSotMap(reasonSot);
        fspsmprlnimport.setReasonDefMap(reasonDef);
        return fspsmprlnimport;
    }

    //判断业务主键
    private boolean isExitDefPrimer(String mdl_id_fk,String ope_no_fk,String samp_path_id_fk,String samp_path_ver_fk, String path_id_fk,
                                 String path_ver_fk,String samp_tpl_id_fk){
        String sql = "select * from ret_samp_tpl_def where 1 = 1";
        if (StringUtils.isNotBlank(mdl_id_fk)) {
            sql = sql + " and mdl_id_fk = '"+mdl_id_fk+"'";
        } else {
            sql = sql + " and mdl_id_fk is null";
        }
        if (StringUtils.isNotBlank(ope_no_fk)) {
            sql = sql + " and ope_no_fk = '"+ope_no_fk+"'";
        } else {
            sql = sql + " and ope_no_fk is null";
        }
        if (StringUtils.isNotBlank(samp_path_id_fk)) {
            sql = sql + " and samp_path_id_fk = '"+samp_path_id_fk+"'";
        } else {
            sql = sql + " and samp_path_id_fk is null";
        }
        if (StringUtils.isNotBlank(samp_path_ver_fk)) {
            sql = sql + " and samp_path_ver_fk = '"+samp_path_ver_fk+"'";
        } else {
            sql = sql + " and samp_path_ver_fk is null";
        }
        if (StringUtils.isNotBlank(path_id_fk)) {
            sql = sql + " and path_id_fk = '"+path_id_fk+"'";
        } else {
            sql = sql + " and path_id_fk is null";
        }
        if (StringUtils.isNotBlank(path_ver_fk)) {
            sql = sql + " and path_ver_fk = '"+path_ver_fk+"'";
        } else {
            sql = sql + " and path_ver_fk is null";
        }

        if (StringUtils.isNotBlank(samp_tpl_id_fk)) {
            sql = sql + " and samp_tpl_id = '"+samp_tpl_id_fk+"'";
        } else {
            sql = sql + " and samp_tpl_id is null";
        }
        List<RetSampTplDef> list = fspsmprlnDao.findBySQL(sql, RetSampTplDef.class);
        boolean flag = false;
        if (list != null && list.size()>0) {
            flag = true;
        }
        return flag;
    }

    //判断slot业务主键
    private boolean isExitSlotPrimer(String slot_set_typ,String act_seq_id,String slot_no){
        String sql = "select * from ret_slot_def where 1 = 1 ";
        if (StringUtils.isNotBlank(slot_set_typ)) {
            sql = sql + " and slot_set_typ = '"+slot_set_typ+"'";
        } else {
            sql = sql + " and slot_set_typ is null";
        }
        if (StringUtils.isNotBlank(act_seq_id)) {
            sql = sql + " and act_seq_id = '"+act_seq_id+"'";
        } else {
            sql = sql + " and act_seq_id is null";
        }
        if (StringUtils.isNotBlank(slot_no)) {
            sql = sql + " and slot_no = '"+slot_no+"'";
        } else {
            sql = sql + " and slot_no is null";
        }
        List<RetSlotDef> list = retSlotDefDao.findBySQL(sql, RetSlotDef.class);
        boolean flag = false;
        if (list != null && list.size()>0) {
            flag = true;
        }
        return flag;
    }

    //判断相同actseq下slotno相同
    private boolean isSameByAct(String act_seq_id,String slot_no) {
        String sql = "select * from ret_slot_def where 1 = 1 ";
        if (StringUtils.isNotBlank(act_seq_id)) {
            sql = sql + " and act_seq_id = '"+act_seq_id+"'";
        }
        List<RetSlotDef> bySQL = retSlotDefDao.findBySQL(sql, RetSlotDef.class);
        boolean flag = false;
        if (bySQL != null && bySQL.size() > 0) {
            for (RetSlotDef retSlotDef : bySQL) {
                if (slot_no.equals(retSlotDef.getSlot_no())) {
                    flag = true;
                }
            }
        }
        return flag;

    }
}
